package simonby.top.annualring.adapter.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import simonby.top.annualring.application.service.FamilyMemberApplicationService;
import simonby.top.annualring.application.service.PermissionApplicationService;
import simonby.top.annualring.domain.model.FamilyMember;
import simonby.top.annualring.adapter.dto.FamilyMemberDTO;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 家族成员控制器
 * 处理家族成员相关的HTTP请求
 */
@RestController
@RequestMapping("/api/members")
public class FamilyMemberController {
    private final FamilyMemberApplicationService familyMemberApplicationService;
    private final PermissionApplicationService permissionApplicationService;

    public FamilyMemberController(FamilyMemberApplicationService familyMemberApplicationService,
                                 PermissionApplicationService permissionApplicationService) {
        this.familyMemberApplicationService = familyMemberApplicationService;
        this.permissionApplicationService = permissionApplicationService;
    }

    /**
     * 创建家族成员
     * @param memberDTO 家族成员DTO
     * @return 创建后的家族成员DTO
     */
    @PostMapping
    public SaResult createFamilyMember(@RequestBody FamilyMemberDTO memberDTO) {
        // 检查用户是否有权限编辑该家族树
        if (!permissionApplicationService.canEditFamilyTree(memberDTO.getFamilyTreeId())) {
            return SaResult.error("无权限在该家族树中添加成员");
        }
        
        FamilyMember member = convertToDomain(memberDTO);
        FamilyMember savedMember = familyMemberApplicationService.createFamilyMember(member);
        return SaResult.ok("创建成功").setData(convertToDTO(savedMember));
    }

    /**
     * 根据ID获取家族成员
     * @param id 成员ID
     * @return 家族成员DTO
     */
    @GetMapping("/{id}")
    public SaResult getFamilyMemberById(@PathVariable Long id) {
        FamilyMemberDTO memberDTO = familyMemberApplicationService.getFamilyMemberById(id)
                .map(this::convertToDTO)
                .orElse(null);
        
        if (memberDTO == null) {
            return SaResult.error("成员不存在");
        }
        
        // 检查用户是否有权限访问该成员所属的家族树
        if (!permissionApplicationService.canAccessFamilyTree(memberDTO.getFamilyTreeId())) {
            return SaResult.error("无权限访问该成员信息");
        }
        
        return SaResult.data(memberDTO);
    }

    /**
     * 根据家族树ID获取所有成员
     * @param familyTreeId 家族树ID
     * @return 家族成员DTO列表
     */
    @GetMapping("/family-tree/{familyTreeId}")
    public SaResult getFamilyMembersByFamilyTreeId(@PathVariable Long familyTreeId) {
        // 检查用户是否有权限访问该家族树
        if (!permissionApplicationService.canAccessFamilyTree(familyTreeId)) {
            return SaResult.error("无权限访问该家族树成员");
        }
        
        List<FamilyMemberDTO> members = familyMemberApplicationService.getFamilyMembersByFamilyTreeId(familyTreeId).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        return SaResult.data(members);
    }

    /**
     * 获取所有家族成员
     * @return 家族成员DTO列表
     */
    @GetMapping
    public List<FamilyMemberDTO> getAllFamilyMembers() {
        // 只有系统管理员可以获取所有家族成员
        if (!permissionApplicationService.isSystemAdmin()) {
            return null;
        }
        
        return familyMemberApplicationService.getAllFamilyMembers().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 更新家族成员
     * @param id 成员ID
     * @param memberDTO 家族成员DTO
     * @return 更新后的家族成员DTO
     */
    @PutMapping("/{id}")
    public SaResult updateFamilyMember(@PathVariable Long id, @RequestBody FamilyMemberDTO memberDTO) {
        // 先获取原始成员信息，检查权限
        FamilyMemberDTO originalMember = familyMemberApplicationService.getFamilyMemberById(id)
                .map(this::convertToDTO)
                .orElse(null);
        
        if (originalMember == null) {
            return SaResult.error("成员不存在");
        }
        
        // 检查用户是否有权限编辑该家族树
        if (!permissionApplicationService.canEditFamilyTree(originalMember.getFamilyTreeId())) {
            return SaResult.error("无权限编辑该成员");
        }
        
        memberDTO.setId(id);
        FamilyMember member = convertToDomain(memberDTO);
        FamilyMember updatedMember = familyMemberApplicationService.updateFamilyMember(member);
        return SaResult.ok("更新成功").setData(convertToDTO(updatedMember));
    }

    /**
     * 删除家族成员
     * @param id 成员ID
     */
    @DeleteMapping("/{id}")
    public SaResult deleteFamilyMember(@PathVariable Long id) {
        // 先获取原始成员信息，检查权限
        FamilyMemberDTO memberDTO = familyMemberApplicationService.getFamilyMemberById(id)
                .map(this::convertToDTO)
                .orElse(null);
        
        if (memberDTO == null) {
            return SaResult.error("成员不存在");
        }
        
        // 检查用户是否有权限编辑该家族树
        if (!permissionApplicationService.canEditFamilyTree(memberDTO.getFamilyTreeId())) {
            return SaResult.error("无权限删除该成员");
        }
        
        familyMemberApplicationService.deleteFamilyMember(id);
        return SaResult.ok("删除成功");
    }

    /**
     * 设置父子关系
     * @param childId 子成员ID
     * @param fatherId 父成员ID
     * @return 更新后的子成员
     */
    @PostMapping("/{childId}/father/{fatherId}")
    public SaResult setFatherRelation(@PathVariable Long childId, @PathVariable Long fatherId) {
        // 检查两个成员是否存在以及权限
        FamilyMemberDTO childDTO = familyMemberApplicationService.getFamilyMemberById(childId)
                .map(this::convertToDTO)
                .orElse(null);
                
        FamilyMemberDTO fatherDTO = familyMemberApplicationService.getFamilyMemberById(fatherId)
                .map(this::convertToDTO)
                .orElse(null);
        
        if (childDTO == null || fatherDTO == null) {
            return SaResult.error("指定的成员不存在");
        }
        
        // 检查权限
        if (!permissionApplicationService.canEditFamilyTree(childDTO.getFamilyTreeId()) ||
            !permissionApplicationService.canEditFamilyTree(fatherDTO.getFamilyTreeId())) {
            return SaResult.error("无权限设置该关系");
        }
        
        // 检查是否属于同一个家族树
        if (!childDTO.getFamilyTreeId().equals(fatherDTO.getFamilyTreeId())) {
            return SaResult.error("成员必须属于同一个家族树");
        }
        
        // 设置父子关系
        Optional<FamilyMember> updatedChild = familyMemberApplicationService.setFatherRelation(childId, fatherId);
        if (updatedChild.isPresent()) {
            return SaResult.ok("父子关系设置成功").setData(convertToDTO(updatedChild.get()));
        } else {
            return SaResult.error("父子关系设置失败");
        }
    }

    /**
     * 设置母子关系
     * @param childId 子成员ID
     * @param motherId 母成员ID
     * @return 更新后的子成员
     */
    @PostMapping("/{childId}/mother/{motherId}")
    public SaResult setMotherRelation(@PathVariable Long childId, @PathVariable Long motherId) {
        // 检查两个成员是否存在以及权限
        FamilyMemberDTO childDTO = familyMemberApplicationService.getFamilyMemberById(childId)
                .map(this::convertToDTO)
                .orElse(null);
                
        FamilyMemberDTO motherDTO = familyMemberApplicationService.getFamilyMemberById(motherId)
                .map(this::convertToDTO)
                .orElse(null);
        
        if (childDTO == null || motherDTO == null) {
            return SaResult.error("指定的成员不存在");
        }
        
        // 检查权限
        if (!permissionApplicationService.canEditFamilyTree(childDTO.getFamilyTreeId()) ||
            !permissionApplicationService.canEditFamilyTree(motherDTO.getFamilyTreeId())) {
            return SaResult.error("无权限设置该关系");
        }
        
        // 检查是否属于同一个家族树
        if (!childDTO.getFamilyTreeId().equals(motherDTO.getFamilyTreeId())) {
            return SaResult.error("成员必须属于同一个家族树");
        }
        
        // 设置母子关系
        Optional<FamilyMember> updatedChild = familyMemberApplicationService.setMotherRelation(childId, motherId);
        if (updatedChild.isPresent()) {
            return SaResult.ok("母子关系设置成功").setData(convertToDTO(updatedChild.get()));
        } else {
            return SaResult.error("母子关系设置失败");
        }
    }

    /**
     * 设置配偶关系
     * @param memberId1 成员1 ID
     * @param memberId2 成员2 ID
     * @return 更新后的成员1
     */
    @PostMapping("/{memberId1}/spouse/{memberId2}")
    public SaResult setSpouseRelation(@PathVariable Long memberId1, @PathVariable Long memberId2) {
        // 检查两个成员是否存在以及权限
        FamilyMemberDTO member1DTO = familyMemberApplicationService.getFamilyMemberById(memberId1)
                .map(this::convertToDTO)
                .orElse(null);
                
        FamilyMemberDTO member2DTO = familyMemberApplicationService.getFamilyMemberById(memberId2)
                .map(this::convertToDTO)
                .orElse(null);
        
        if (member1DTO == null || member2DTO == null) {
            return SaResult.error("指定的成员不存在");
        }
        
        // 检查权限
        if (!permissionApplicationService.canEditFamilyTree(member1DTO.getFamilyTreeId()) ||
            !permissionApplicationService.canEditFamilyTree(member2DTO.getFamilyTreeId())) {
            return SaResult.error("无权限设置该关系");
        }
        
        // 检查是否属于同一个家族树
        if (!member1DTO.getFamilyTreeId().equals(member2DTO.getFamilyTreeId())) {
            return SaResult.error("成员必须属于同一个家族树");
        }
        
        // 设置配偶关系
        Optional<FamilyMember> updatedMember1 = familyMemberApplicationService.setSpouseRelation(memberId1, memberId2);
        if (updatedMember1.isPresent()) {
            return SaResult.ok("配偶关系设置成功").setData(convertToDTO(updatedMember1.get()));
        } else {
            return SaResult.error("配偶关系设置失败");
        }
    }

    /**
     * 获取成员的直接亲属（父亲、母亲、配偶、子女）
     * @param memberId 成员ID
     * @return 直接亲属列表
     */
    @GetMapping("/{memberId}/relatives")
    public SaResult getDirectRelatives(@PathVariable Long memberId) {
        // 检查成员是否存在及权限
        FamilyMemberDTO memberDTO = familyMemberApplicationService.getFamilyMemberById(memberId)
                .map(this::convertToDTO)
                .orElse(null);
        
        if (memberDTO == null) {
            return SaResult.error("指定的成员不存在");
        }
        
        // 检查权限
        if (!permissionApplicationService.canAccessFamilyTree(memberDTO.getFamilyTreeId())) {
            return SaResult.error("无权限访问该成员信息");
        }
        
        // 获取直接亲属
        List<FamilyMemberDTO> relatives = familyMemberApplicationService.getDirectRelatives(memberId)
                .stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
                
        return SaResult.data(relatives);
    }

    /**
     * 将FamilyMemberDTO转换为FamilyMember领域对象
     * @param memberDTO 家族成员DTO
     * @return FamilyMember领域对象
     */
    private FamilyMember convertToDomain(FamilyMemberDTO memberDTO) {
        FamilyMember member = new FamilyMember();
        member.setId(memberDTO.getId());
        member.setName(memberDTO.getName());
        member.setGender(memberDTO.getGender());
        member.setBirthDate(memberDTO.getBirthDate());
        member.setDeathDate(memberDTO.getDeathDate());
        member.setBiography(memberDTO.getBiography());
        member.setPhotoUrl(memberDTO.getPhotoUrl());
        member.setLatitude(memberDTO.getLatitude());
        member.setLongitude(memberDTO.getLongitude());
        member.setFamilyTreeId(memberDTO.getFamilyTreeId());
        member.setFatherId(memberDTO.getFatherId());
        member.setMotherId(memberDTO.getMotherId());
        member.setSpouseId(memberDTO.getSpouseId());
        member.setCreateTime(memberDTO.getCreateTime());
        member.setUpdateTime(memberDTO.getUpdateTime());
        return member;
    }

    /**
     * 将FamilyMember领域对象转换为FamilyMemberDTO
     * @param member FamilyMember领域对象
     * @return 家族成员DTO
     */
    private FamilyMemberDTO convertToDTO(FamilyMember member) {
        FamilyMemberDTO memberDTO = new FamilyMemberDTO();
        memberDTO.setId(member.getId());
        memberDTO.setName(member.getName());
        memberDTO.setGender(member.getGender());
        memberDTO.setBirthDate(member.getBirthDate());
        memberDTO.setDeathDate(member.getDeathDate());
        memberDTO.setBiography(member.getBiography());
        memberDTO.setPhotoUrl(member.getPhotoUrl());
        memberDTO.setLatitude(member.getLatitude());
        memberDTO.setLongitude(member.getLongitude());
        memberDTO.setFamilyTreeId(member.getFamilyTreeId());
        memberDTO.setFatherId(member.getFatherId());
        memberDTO.setMotherId(member.getMotherId());
        memberDTO.setSpouseId(member.getSpouseId());
        memberDTO.setCreateTime(member.getCreateTime());
        memberDTO.setUpdateTime(member.getUpdateTime());
        return memberDTO;
    }
}